package com.orangelife.service.propFeeAccount.impl;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;

import com.orangelife.exception.AppBizException;
import com.orangelife.redis.core.redis.session.redisSession.WebServiceSession;
import com.orangelife.service.Importlogs.QiniuUtils;
import com.orangelife.service.propFeeAccount.IPropFeeAccountService;
import com.orangelife.service.propFeeAccountImportLog.IPropFeeAccountImportLogService;
import com.orangelife.service.propFeeAccountImportLog.model.PropFeeAccountImportLogDto;
import com.orangelife.service.propFeeApartment.IPropFeeApartmentService;
import com.orangelife.utils.IdUtil;
import com.orangelife.utils.ListSetUtils;
import com.orangelife.utils.StringUtils;

@Service("importAccount")
public class ImportAccountImpl implements IImportAccount {

	@Resource(name = "propFeeAccountService")
	private IPropFeeAccountService propFeeAccountService;

	@Resource(name = "propFeeAccountImportLogService")
	private IPropFeeAccountImportLogService propFeeAccountImportLogService;

	private QiniuUtils qiniuUtils = new QiniuUtils();

	@Resource(name = "propFeeApartmentService")
	private IPropFeeApartmentService propFeeApartmentService;

	@Override
	public int importAccount(String commID, Sheet sheet, WebServiceSession webServiceSession,
							 String fileName) throws AppBizException {
		PropFeeAccountImportLogDto cmmImportLog = new PropFeeAccountImportLogDto();
		Map<Integer, String> logmap = new TreeMap<Integer, String>();
		int rowCount = sheet.getPhysicalNumberOfRows();// 获得总行数
		if (rowCount < 1) {
			throw new AppBizException(2, "sheet页无数据");
		}

		/****
		 * 添加失败日志
		 */

		cmmImportLog.setCreateuserID("1");
		cmmImportLog.setImportLogID(IdUtil.getuuId());
		cmmImportLog.setItemStat("1");
		cmmImportLog.setStatus("1");
		cmmImportLog.setTscreate(new Date());
		cmmImportLog.setTsedit(new Date());
		cmmImportLog.setFileName(fileName);
		propFeeAccountImportLogService.addPropFeeAccountImportLog(cmmImportLog);
		Row row = sheet.getRow(0);// 第一行
		int columnCount = row.getLastCellNum();// 获取列数
		Map<String, Integer> columnMap = new HashMap<String, Integer>();
		for (int i = 0; i < columnCount; i++) {
			String columnName = row.getCell((short) i).getStringCellValue()
					.trim();
			if (columnName.equals("楼栋")) {
				columnMap.put("楼栋", i);
			}

			if (columnName.equals("房号")) {
				columnMap.put("房号", i);
			}
			if (columnName.equals("单元")) {
				columnMap.put("单元", i);
			}
			if (columnName.equals("金额")) {
				columnMap.put("金额", i);
			}
		}

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("commID", commID);
		List<Map<String, Object>> houseInfos = propFeeApartmentService
				.getHouseInfo(map);
		try {
			checkRecordColum(columnMap, commID, cmmImportLog, logmap);
		} catch (Exception e) {
			return 0;
		}

		Set<Map<String, Object>> recordDtos = notNull(sheet, commID, rowCount,
				columnMap, houseInfos, cmmImportLog, logmap);
		ListSetUtils listSetUtils = new ListSetUtils();
		List<List<Map<String, Object>>> li = listSetUtils.splitList(
				listSetUtils.setToList(recordDtos), 200);
		for (int i = 0; i < li.size(); i++) {
			HandleAccountThread thread = new HandleAccountThread(commID, "线程["
					+ (i) + "] ", li.get(i), propFeeAccountService, webServiceSession,
					houseInfos);
			thread.start();
		}
		return columnCount;

	}

	public Set<Map<String, Object>> notNull(Sheet sheet, String commID,
											int rowCount, Map<String, Integer> columnMap,
											List<Map<String, Object>> houseInfos,
											PropFeeAccountImportLogDto cmmImportLog, Map<Integer, String> logmap)
			throws AppBizException {
		int errortol = 0;
		int total = 0;
		Set<Map<String, Object>> propFeeMeterRecordDtos = new HashSet<Map<String, Object>>();
		Row firstRow = sheet.getRow(1);
		if (firstRow == null) {
			throw new AppBizException(99, "亲，请最少填写一行信息");
		}

		for (int i = 1; i < rowCount; i++) {
			try {
				Map<String, Object> account = new HashMap<String, Object>();
				Row dataRow = sheet.getRow(i);
				if (dataRow == null) {
					break;
				}
				if (2 == (getCellInfoByHouseInfo(i + 1, dataRow, columnMap,
						logmap, houseInfos, propFeeMeterRecordDtos))) {
					errortol++;
					continue;
				} else if (1 == (getCellInfoByHouseInfo(i + 1, dataRow,
						columnMap, logmap, houseInfos, propFeeMeterRecordDtos))) {
					logmap.put(i + 1, "该行出现了的空行，导入停止");
					break;

				} else if (3 == (getCellInfoByHouseInfo(i + 1, dataRow,
						columnMap, logmap, houseInfos, propFeeMeterRecordDtos))) {
					// logmap.put(j + 1, "该行出现了的空行，导入停止");
					break;

				}

				/*
				 * if
				 * (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				 * .get("楼栋"))))) { throw new AppBizException(2, "亲，第" + i + 1 +
				 * "行楼栋为空"); }
				 */
				account.put("buildingName",
						this.getCellValue(dataRow.getCell(columnMap.get("楼栋"))));
				/*
				 * if
				 * (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				 * .get("房号"))))) { throw new AppBizException(2, "亲，第" + i + 1 +
				 * "行房号为空"); }
				 */

				account.put("apartmentName",
						this.getCellValue(dataRow.getCell(columnMap.get("房号"))));

				String unitName = this.getCellValue(dataRow.getCell(columnMap
						.get("单元")));

				if (!StringUtils.isBlank(unitName)) {
					account.put("unitName", unitName);
				} else {
					account.put("unitName", null);
				}

				account.put("rowNum", i);
				/*
				 * if
				 * (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				 * .get("金额"))))) { throw new AppBizException(2, "亲，第" + i + 1 +
				 * "行 金额为空"); }
				 */
				// String val = this.getCellValue(row2.getCell(eType.get(key)),
				// "0.##");
				/*
				 * if (!StringUtils.isDouble(this.getCellValue(
				 * dataRow.getCell(columnMap.get("金额")), "0.##"))) { throw new
				 * AppBizException(2, "亲，第" + i + 1 + "行 金额格式错误"); }
				 */
				account.put("money", this.getCellValue(
						dataRow.getCell(columnMap.get("金额")), "0.##"));
				propFeeMeterRecordDtos.add(account);
				total++;
			} catch (AppBizException e) {
				e.printStackTrace();
				logmap.put(i + 1, "行数据转换错误,错误原因：" + e.getMessage());
				errortol++;

			}
		}
		cmmImportLog.setStatus("2");
		cmmImportLog.setImportInfo("成功" + total + "条" + ",失败" + errortol + "条");
		String logurl = qiniuUtils.createErrorLogFile(logmap);
		cmmImportLog.setLink(logurl);

		cmmImportLog.setFinishTime(new Date(new Date().getTime() + 1000 * total
				* 4));
		cmmImportLog.setTsedit(new Date());
		cmmImportLog.setCommID(commID);
		propFeeAccountImportLogService
				.editPropFeeAccountImportLog(cmmImportLog);
		return propFeeMeterRecordDtos;

	}

	public void checkRecordColum(Map<String, Integer> map, String commID,
								 PropFeeAccountImportLogDto cmmImportLog, Map<Integer, String> logmap)
			throws AppBizException {
		try {
			if (map == null || map.size() <= 0) {
				throw new AppBizException(99, "亲,使用正确的excel的格式");
			}

			if (!map.containsKey("楼栋")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少楼栋)");
			}
			if (!map.containsKey("房号")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少房号)");
			}
			if (!map.containsKey("单元")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少单元)");
			}
			if (!map.containsKey("金额")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少金额)");
			}

		} catch (Exception e) {

			logmap.put(1, e.getMessage());
			/****
			 * 添加失败日志
			 */
			cmmImportLog.setStatus("3");
			cmmImportLog.setImportInfo("成功0条");
			String logurl = qiniuUtils.createErrorLogFile(logmap);
			cmmImportLog.setLink(logurl);
			cmmImportLog.setFinishTime(new Date());
			cmmImportLog.setTsedit(new Date());
			cmmImportLog.setCommID(commID);
			propFeeAccountImportLogService
					.editPropFeeAccountImportLog(cmmImportLog);
			throw new AppBizException(99, e.getMessage());

		}

	}

	public int getCellInfoByHouseInfo(int rownum, Row dataRow,
									  Map<String, Integer> columnMap, Map<Integer, String> logmap,
									  List<Map<String, Object>> houseInfos,
									  Set<Map<String, Object>> propFeeMeterRecordDtos)
			throws AppBizException {

		/***
		 * 跳过空白行
		 */
		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("楼栋"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
				.getCell(columnMap.get("房号"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
				.getCell(columnMap.get("单元"))))) {
			return 1;

		}
		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("楼栋"))))) {
			logmap.put(rownum, "亲，第" + rownum + "行楼栋为空");
			return 2;
			// throw new AppBizException(2, "亲，第" + i + "行楼栋为空");
		}

		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("房号"))))) {
			// throw new AppBizException(2, "亲，第" + i + "行房号为空");
			logmap.put(rownum, "亲，第" + rownum + "行房号为空");
			return 2;
		}

		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("金额"))))) {
			// throw new AppBizException(2, "亲，第" + i + "行 是否预缴为空");

			logmap.put(rownum, "亲，第" + rownum + "行是金额为空");
			return 2;
		}
		if (!StringUtils.isDouble(this.getCellValue(
				dataRow.getCell(columnMap.get("金额")), "0.##"))) {
			// throw new AppBizException(2, "亲，第" + rownum + "行 金额格式错误");
			logmap.put(rownum, "亲，第" + rownum + "行 金额格式错误");
			return 2;
		}
		boolean isCheck = false;
		String unitName = this
				.getCellValue(dataRow.getCell(columnMap.get("单元")));
		String buildingName = this.getCellValue(dataRow.getCell(columnMap
				.get("楼栋")));
		String apartmentName = this.getCellValue(dataRow.getCell(columnMap
				.get("房号")));

		if (propFeeMeterRecordDtos != null && propFeeMeterRecordDtos.size() > 0) {
			boolean isExIst = false;
			String row = "";
			for (Map<String, Object> map : propFeeMeterRecordDtos) {
				if (StringUtils.isBlank(unitName)) {
					if (buildingName.equals(map.get("buildingName").toString())
							&& apartmentName.equals(map.get("apartmentName")
							.toString())) {
						isExIst = true;
						row = map.get("rowNum").toString();
						break;
					}
				} else {
					if (map.get("buildingName").toString().equals(buildingName)
							&& map.get("apartmentName").toString()
							.equals(apartmentName)
							&& unitName.equals(map.get("unitName").toString())) {
						isExIst = true;
						row = map.get("rowNum").toString();
						break;
					}
				}

			}
			if (isExIst) {
				logmap.put(rownum, "亲，第"
						+ rownum
						+ "行 楼栋"
						+ buildingName
						+ "-"
						+ (StringUtils.isBlank(unitName) ? "" : "单元" + unitName
						+ "-") + "房号为" + apartmentName + "房屋信息与" + row
						+ "行信息重复");
				return 2;
			}
		}
		for (Map<String, Object> house : houseInfos) {
			if (StringUtils.isBlank(unitName)) {
				if (house.get("buildingName").toString().equals(buildingName)
						&& house.get("apartmentNum").toString()
						.equals(apartmentName)
						&& StringUtils.isBlank(StringUtils.toString(house
						.get("unitName")))) {
					isCheck = true;
					break;
				}
			} else {
				if (house.get("buildingName").toString().equals(buildingName)
						&& house.get("apartmentNum").toString()
						.equals(apartmentName)
						&& unitName.equals(StringUtils.toString(house.get("unitName")))) {
					isCheck = true;
					break;
				}
			}

		}
		if (!isCheck) {
			logmap.put(rownum, "亲，第"
					+ rownum
					+ "行 楼栋"
					+ buildingName
					+ "-"
					+ (StringUtils.isBlank(unitName) ? "" : "单元" + unitName
					+ "-") + "房号为" + apartmentName + "房屋信息在该小区不存在");
			return 2;
		}
		return 0;
	}

	public String getCellValue(Cell cell) throws AppBizException {
		String cellValue = null;
		try {
			if (cell != null) {
				switch (cell.getCellType()) {
					case Cell.CELL_TYPE_NUMERIC: {
						if (DateUtil.isCellDateFormatted(cell)) {
							Date date = cell.getDateCellValue();
							SimpleDateFormat format = new SimpleDateFormat(
									"yyyy-MM-dd HH:mm:ss");
							cellValue = format.format(date);

						} else {
							DecimalFormat df = new DecimalFormat("#");
							cellValue = df.format(cell.getNumericCellValue());

						}
					}
					break;
					case Cell.CELL_TYPE_STRING: {
						cellValue = cell.getStringCellValue().trim();
					}
					break;

					default:
						break;
				}
			}
		} catch (Exception e) {
			throw new AppBizException(99, e.getMessage());
		}
		return cellValue;
	}

	private String getCellValue(Cell cell, String format1)
			throws AppBizException {
		String cellValue = null;
		try {
			if (cell != null) {
				switch (cell.getCellType()) {
					case Cell.CELL_TYPE_NUMERIC: {
						if (DateUtil.isCellDateFormatted(cell)) {
							Date date = cell.getDateCellValue();
							SimpleDateFormat format = new SimpleDateFormat(
									"yyyy-MM-dd HH:mm:ss");
							cellValue = format.format(date);

						} else {
							DecimalFormat df = new DecimalFormat(
									format1 == null ? "#" : format1);
							cellValue = df.format(cell.getNumericCellValue());
							// cellValue = String.valueOf((int) cell
							// .getNumericCellValue());
						}
					}
					break;
					case Cell.CELL_TYPE_STRING: {
						cellValue = cell.getStringCellValue().trim();
					}
					break;

					default:
						break;
				}
			}
		} catch (Exception e) {
			throw new AppBizException(99, e.getMessage());
		}
		return cellValue;
	}

	public boolean getTimeDate(String date) {
		String eL = "[0-9]{4}-[0-9]{2}";
		Pattern p = Pattern.compile(eL);
		Matcher m = p.matcher(date);
		boolean dateFlag = m.matches();
		if (!dateFlag) {
			return false;
		}
		return true;
	}

}